#include <QikListBoxModel.h>
#include <QikListBox.h>
#include <MQikListBoxData.h>
#include <QikListBoxData.h>
#include <QikContent.h>
#include <QikZoomDlg.h>
#include <QikCommand.h>

#include "PinQPacketsView.h"
#include "PinQDocument.h"
#include "PinQTask.h"
#include "PinQExternalInterface.h"
#include "PinQ.hrh"
#include <PinQ.rsg>
#include <PinQ.mbg>

CPinQPacketsView* CPinQPacketsView::NewLC(CQikAppUi& aAppUi,
		const TVwsViewId aParentViewId)
	{
	CPinQPacketsView* self = new (ELeave) CPinQPacketsView(aAppUi,aParentViewId);
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
	}

CPinQPacketsView::CPinQPacketsView(CQikAppUi& aAppUi,
		const TVwsViewId aParentViewId) :
	CQikViewBase(aAppUi, aParentViewId)
	{
	}

CPinQPacketsView::~CPinQPacketsView()
	{
	}

void CPinQPacketsView::ConstructL()
	{
	BaseConstructL();
	}

TVwsViewId CPinQPacketsView::ViewId() const
	{
	return TVwsViewId(KUidPinQApp, KUidPinQPacketsView);
	}

void CPinQPacketsView::HandleCommandL(CQikCommand& aCommand)
	{
	CPinQAppUi* appUi = static_cast<CPinQAppUi*>(iCoeEnv->AppUi());
	switch (aCommand.Type())
		{
		case EQikCommandTypeCancel:
		case EQikCommandTypeDone:
			TVwsViewId listView = TVwsViewId(KUidPinQApp, KUidPinQListView);
			iQikAppUi.ActivateViewL(listView);

			RequestFocusL(NULL);
			return;
		case EQikCommandTypeScreen:
			switch (aCommand.Id())
				{
				case EPinQBackCmd:
					TVwsViewId listView = TVwsViewId(KUidPinQApp,
							KUidPinQListView);
					iQikAppUi.ActivateViewL(listView);

					RequestFocusL(NULL);
					return;
				case EPinQZoomCmd:
					{
					CPinQDocument* document =
							static_cast<CPinQDocument*>(iQikAppUi.Document());
					const TInt zoomFactor =
							CQikZoomDialog::RunDlgLD(document->Preferences().ListViewZoomState());

					if (document->Preferences().SetListViewZoomState(zoomFactor))
						{
						SetZoomFactorL(zoomFactor);
						}
					return;
					}
				}
		}
	CQikViewBase::HandleCommandL(aCommand);

	}

void CPinQPacketsView::ViewConstructL()
	{
	ViewConstructFromResourceL(R_PINQ_PACKETS_CONFIGURATIONS);

	CPinQDocument* document = static_cast<CPinQDocument*>(iQikAppUi.Document());
	SetZoomFactorL(document->Preferences().ListViewZoomState());
	}

_LIT(KPacketOkFmt, "%d(%d) %d.%03d");
_LIT(KPacketTOFmt, "%d(%d) t/o");

void CPinQPacketsView::ViewActivatedL(const TVwsViewId& aPrevViewId,
		const TUid aCustomMessageId, const TDesC8& aCustomMessage)
	{
	//ensure called in right way
	ASSERT(aPrevViewId.iAppUid == KUidPinQApp);
	ASSERT(aCustomMessageId == KUidPinQDnlItem);
	//unpack input data
	TPinQDnlItemBuf buf;
	buf.Copy(aCustomMessage);
	iCurrentTaskUid = buf().iUid;
	const CPinQTask& task=PinQModel().Task(iCurrentTaskUid);
	//start work with listbox
	CQikListBox* listBox =
			LocateControlByUniqueHandle<CQikListBox>(EPinQPacketsViewListCtrl);

	MQikListBoxModel& model(listBox->Model());
	//remove data from previous activation
	listBox->RemoveAllItemsL();
	//add packetst from task
	model.ModelBeginUpdateLC();
	for (CPinQTask::TPacket* p=task.FirstPacket(); p; p=p->iNext)
		{
		TBuf<256> buf;
		MQikListBoxData* listBoxData =
				model.NewDataL(MQikListBoxModel::EDataNormal);
		CleanupClosePushL(*listBoxData);
		if (p->iError==CPinQTask::ETimeout)
			buf.Format(KPacketTOFmt, p->iSeq, p->iReceSeq);
		else
			buf.Format(KPacketOkFmt, p->iSeq, p->iReceSeq, p->iTime/1000,
					p->iTime % 1000);
		listBoxData->AddTextL(buf, EQikListBoxSlotText1);
		CleanupStack::PopAndDestroy(listBoxData);
		}
	model.ModelEndUpdateL();
	if (model.Count())
		listBox->SetCurrentItemIndexL(model.Count()-1, ETrue, EDrawNow);
	}

void CPinQPacketsView::TaskStateChangedL(const CPinQTask& aTask,
		CPinQTask::TState aNewState)
	{
	ASSERT(iCurrentTaskUid==aTask.Uid());
	CPinQTask::TPacket* last=aTask.LastPacket();
	ASSERT(last);

	CQikListBox* listBox =
			LocateControlByUniqueHandle<CQikListBox>(EPinQPacketsViewListCtrl);

	MQikListBoxModel& model(listBox->Model());
	model.ModelBeginUpdateLC();

	TBuf<256> buf;
	if (last->iError==CPinQTask::ETimeout)
		buf.Format(KPacketTOFmt, last->iSeq, last->iReceSeq);
	else
		buf.Format(KPacketOkFmt, last->iSeq, last->iReceSeq, last->iTime/1000,
				last->iTime % 1000);

	TUint index=model.Count()-1;
	if (aNewState==CPinQTask::ESending)
		{
		if (aTask.Pref().Loop() &&  (aTask.PacketsCount()==model.Count()))
				model.RemoveDataL(0); //PacketsCount >0 because last!=NULL
			else
				index=model.Count();
		MQikListBoxData* listBoxData =
				model.NewDataL(MQikListBoxModel::EDataNormal);
		CleanupClosePushL(*listBoxData);
		listBoxData->AddTextL(buf, EQikListBoxSlotText1);
		CleanupStack::PopAndDestroy(listBoxData);
		}
	else
		{
		ASSERT(model.Count());
		index=model.Count()-1;
		MQikListBoxData* ListBoxData = model.RetrieveDataL(index);
		CleanupClosePushL(*ListBoxData);
		ListBoxData->SetTextL(buf, EQikListBoxSlotText1);
		CleanupStack::PopAndDestroy(ListBoxData);
		}
	model.DataUpdatedL(index);
	model.ModelEndUpdateL();
	if (aNewState==CPinQTask::ESending)
		if (model.Count())
			listBox->SetCurrentItemIndexL(model.Count()-1, ETrue, EDrawNow);
	}

void CPinQPacketsView::SetZoomFactorL(TInt aZoomLevel)
	{
	const TInt zoomFactor = CQikAppUi::ZoomFactorL(aZoomLevel, *iEikonEnv);
	CQikViewBase::SetZoomFactorL(zoomFactor);
	}

// vim: ts=2:sw=2
